package thread;

import com.sun.org.apache.bcel.internal.generic.NEW;

/**
 * 线程并发安全问题
 * 同步块:
 * synchronized(同步监视器对象){
 *     需要多个线程同时执行的代码代码
 * }
 */
public class SyncDemo1 {
    public static void main(String[] args) {
        /*
        Shop shop = new Shop();
        Thread t1 = new Thread("吴克勤"){
            public void run(){
                shop.buy();
            }
        };
        Thread t2 = new Thread("范冰冰"){
            public void run(){
                shop.buy();
            }
        };
        t1.start();
        t2.start();
         */

        //不同商店的效果
        Shop shop1 = new Shop();
        Shop shop2 = new Shop();
        /*
        Thread t1 = new Thread("吴克勤"){
            public void run(){
                shop1.buy();
            }
        };
        Thread t2 = new Thread("范冰冰"){
            public void run(){
                shop2.buy();
            }
        };
        */

        Thread t1 = new Thread(shop1::buy);//方法参数相同才可以简写
        Thread t2 = new Thread(shop2::buy);
        t1.start();
        t2.start();
    }
}

class Shop{

    //public synchronized void buy(){//在方法上同步监视(锁),范围比较大,同步监视(锁)对象只能是this
    public void buy(){
        //试衣间模拟安全并发问题
        try {
            Thread t = Thread.currentThread();
            System.out.println(t.getName()+": 正在挑选衣服");//可以同时访问
            Thread.sleep(3000);
            /*
             * 同步监视对象可以是任意对象, 但是必须是同一个对象, 否则无法同步
             *
             */
            //synchronized(new Object()){ //永远不能用实例化的对象作为同步监视器(锁)对象， 一定无效
            //synchronized(123){ //同步监视器(锁)对象一定是引用类型
            synchronized("abc"){// 虽然可以, 但abc并不是合适的锁对象
            //synchronized(this){//在代码块中同步监视块, 缩小监视范围, this锁住当前对象
                System.out.println(t.getName()+": 正在试衣服");//不可同时访问
                Thread.sleep(3000);
            }
            System.out.println(t.getName()+": 结账离开");//可以同时访问
        } catch (InterruptedException e) {
           e.printStackTrace();
        }
    }
}
